package fw.helpers;

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fw.ApplicationManager;

public class WebElementHelper {
	ApplicationManager app;
	public boolean acceptNextAlert = true;
	private static Logger LOG = LoggerFactory.getLogger(WebElementHelper.class);

	public WebElementHelper(ApplicationManager app) {
		this.app = app;
	}

	/**
	 * Check element for presence
	 * 
	 * @param webElement
	 * @return boolean
	 */
	public boolean isElementPresent(WebElement webElement) {
		LOG.info("Check for is an element present");
		if (webElement != null) {
			LOG.info("Element found");
			return true;
		} else {
			LOG.warn("Element not found");
			return false;
		}
	}

	public boolean isElementPresent(Select Select) {
		LOG.info("Check for is an element present");

		if (Select != null) {
			LOG.info("Select found");
			return true;
		} else {
			LOG.warn("Select not found");
			return false;
		}
	}

	/**
	 * Check for visibilityOf element
	 * 
	 * @param webElement
	 * @return boolean
	 */
	public boolean isElementVisible(WebElement webElement) {
		LOG.info("Check for is an element visible");
		try {
			app.wait.until(ExpectedConditions.visibilityOf(webElement));
			LOG.info("Element is visible");
			return true;
		} catch (Exception ex) {
			LOG.debug("Element is not visible");
			return false;
		}

	}

	/**
	 * Pauses for timeout seconds
	 * 
	 * @param timeout
	 */
	public void pause(int timeout) {
		try {
			Thread.sleep(timeout * 1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Waits for disappearing WebElement
	 * 
	 * @param shouldDisappearWebElement
	 */
	public void waitForDisappear(WebElement shouldDisappearWebElement) {
		while (isElementVisible(shouldDisappearWebElement)) {
			pause(1);
		}
	}

	public void type(WebElement webElement, String value) {
		if (isElementPresent(webElement)) {
			try {
				webElement.clear();
				webElement.sendKeys(value);
			} catch (Exception ex) {
				LOG.warn("Can not type to element");
				LOG.warn(ex.toString());
			}
		}
	}

	public void click(WebElement webElement) {
		LOG.debug("Click on webElement");

		if (isElementVisible(webElement)) {
			try {
				webElement.click();
			} catch (Exception ex) {
				LOG.warn("Cannot click on webElement");
				LOG.warn(ex.toString());
			}
		}
	}

	/**
	 * Gets text from webElement
	 * 
	 * @param webElement
	 * @return String text
	 */
	public String getText(WebElement webElement) {
		return getAttribute(webElement, "text");
	}

	/**
	 * Gets attribute value from webElement
	 * 
	 * @param webElement
	 * @param attribute
	 * @return String attribute value
	 */
	public String getAttribute(WebElement webElement, String attribute) {
		LOG.debug("Get " + attribute + " from element");
		String attributeValue = "1";

		if (isElementPresent(webElement)) {
			try {
				if (attribute.equals("text")) {
					attributeValue = webElement.getText();
				} else {
					attributeValue = webElement.getAttribute(attribute);
				}
			} catch (Exception ex) {
				LOG.warn("Can not get " + attribute + " from element");
				LOG.warn(ex.toString());
			}
		} else {
			LOG.warn("element is not present in the DOM");
		}
		return attributeValue;
	}

	/**
	 * set select value by text
	 * 
	 * @param select
	 * @param text
	 */
	public void setSelectByText(Select select, String text) {
		if (!select.getOptions().isEmpty()) {
			if (text.isEmpty()) {
				setSelectByIndex(select, app.randomize().getRandomInt(1, select.getOptions().size() - 1));
			} else {
				try {
					select.selectByVisibleText(text);
				} catch (Exception ex) {
					LOG.warn("Cannot select option by text: " + text + ": " + ex.toString());
				}
			}
		}
	}

	/**
	 * set select value by index
	 * 
	 * @param select
	 * @param p_index
	 */
	public void setSelectByIndex(Select select, int index) {
		try {
			select.selectByIndex(index);
		} catch (Exception ex) {
			LOG.warn("Cannot select a random option: " + ex.toString());
		}
	}

	/**
	 * set select value by value property
	 * 
	 * @param select
	 * @param value
	 */
	public void setSelectByValue(Select select, String value) {
		try {
			if (!select.getOptions().isEmpty()) {
				select.selectByValue(value);
			}
		} catch (Exception ex) {
			LOG.warn("Cannot select option by value: " + value + ": " + ex.toString());
		}
	}
}
